<?php

/**
 * Created by PhpStorm.
 * User: yappy
 * Date: 16/5/4
 * Time: 下午6:48
 */
namespace common\components;
require_once __DIR__ . "/weixin/WxPay.Api.php";
//require_once __DIR__ . "/weixin/WxPay.JsApiPay.php";
require_once __DIR__ . "/weixin/WxPay.Data.php";
require_once __DIR__ . "/weixin/WxPay.Exception.php";
use common\models\OrderPay;
use common\service\FormInfoService;
use Yii;
use yii\helpers\Url;
use yii\log\Logger;
use common\service\PubService;

class Weixin
{
    protected $wechat;

    private function __CreateOauthUrlForCode($redirectUrl)
    {

        $urlObj["appid"] = $this->wechat->appid;
        $urlObj["redirect_uri"] = "$redirectUrl";
        $urlObj["response_type"] = "code";
        $urlObj["scope"] = "snsapi_base";
        $urlObj["state"] = "STATE" . "#wechat_redirect";
        $bizString = self::ToUrlParams($urlObj);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?" . $bizString;
    }

    /**
     *
     * 拼接签名字符串
     * @param array $urlObj
     *
     * @return 返回已经拼接好的字符串
     */
    private static function ToUrlParams($urlObj)
    {
        $buff = "";
        foreach ($urlObj as $k => $v) {
            if ($k != "sign") {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    public function GetOpenidFromMp($code)
    {
        $url = $this->__CreateOauthUrlForOpenid($code);
        //初始化curl
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);//$this->curl_timeout);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        //运行curl，结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res, true);

        try {
            $openid = $data['openid'];
            if ($openid) {
                //一天缓存
                Yii::$app->session->set(md5('openid'), $openid);
            }
        } catch (\Exception $ex) {
            $openid = str_replace('-', '', String::uuid());
            //一天缓存
            Yii::$app->session->set(md5('openid'), $openid);
        }

        return $openid;
    }

    /**
     *
     * 构造获取open和access_toke的url地址
     * @param string $code ，微信跳转带回的code
     *
     * @return 请求的url
     */
    private function __CreateOauthUrlForOpenid($code)
    {
        $cacheKey = md5(\Yii::$app->params['findWechat_token']);
        $this->wechat = \Yii::$app->cache->get($cacheKey);
        $urlObj["appid"] = $this->wechat->appid;
        $urlObj["secret"] = $this->wechat->appsecret;
        $urlObj["code"] = $code;
        $urlObj["grant_type"] = "authorization_code";
        $bizString = $this->ToUrlParams($urlObj);
        return "https://api.weixin.qq.com/sns/oauth2/access_token?" . $bizString;
    }

    /**
     * 获取用户openid
     * @return null|\用户的openid
     */
    public function getWeixinOpenId($exhibitionId)
    {
        if (null == $openid = \Yii::$app->session->get(md5('openid'))) {
            $this->wechat = PubService::findWechatConfig($exhibitionId);
            //通过code获得openid
            if (!isset($_GET['code'])) {
                //触发微信返回code码
                $proxy = \Yii::$app->params['apiUrl'] . "/proxy.php?u=%s";
                $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
                $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
                $baseUrl = urlencode($url);
                \Yii::getLogger()->log('TRACE:' . 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . $_SERVER['QUERY_STRING']
                    . '  encoded base url:' . $baseUrl, Logger::LEVEL_INFO);
                $proxyUrl = urlencode(sprintf($proxy, $baseUrl));
                \Yii::getLogger()->log('TRACE:' . sprintf($proxy, $baseUrl)
                    . '  encoded proxy url:' . $baseUrl, Logger::LEVEL_INFO);
                $url = $this->__CreateOauthUrlForCode($proxyUrl);
                Header("Location: $url");
                exit();
            } else {
                //获取code码，以获取openid
                $code = $_GET['code'];
                $openid = $this->getOpenidFromMp($code);
                return $openid;
            }
        }
        return $openid;

    }

    public function createOrder($orderId, $name, $deposit, $expireTime, $notifyUrl = '')
    {

        $orderPayInfo = FormInfoService::getUserInfoByUuid($orderId);
        $this->wechat = PubService::findWechatConfig($orderPayInfo['exhibition_id']);
        $input = new \WxPayUnifiedOrder();
        $input->SetAppid($this->wechat->appid);
        $input->SetMch_id($this->wechat->wx_mchid);
        $input->SetDevice_info("WEB");
        $input->SetBody($name);

        $input->SetTime_start(date('YmdHis', time()));
        $input->SetTime_expire(date('YmdHis', $expireTime));
        Yii::getLogger()->log('Weixinpay order created, time:' . json_encode(['s' => $input->GetTime_start(),
                'e' => $input->GetTime_expire()]),
            Logger::LEVEL_INFO);
        $input->SetTotal_fee($deposit);
        $input->SetTrade_type('NATIVE');

        $input->SetOut_trade_no($orderId);


        if (empty($notifyUrl)) {
            $notifyUrl = $this->wechat->wx_notify_url;
        }
        $input->SetNotify_url(Url::toRoute($notifyUrl, true));

        $order = \WxPayApi::unifiedOrder($input);
        return $order;


    }

    /**
     * 扫码
     * @param $exhibitionId
     * @param $name
     * @param $deposit
     * @param $expireTime
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function createNative($orderId, $exhibitionId, $name, $deposit, $expireTime,$wx_notify_url = '')
    {
        $this->wechat = PubService::findWechatConfig($exhibitionId);
        $input = new \WxPayUnifiedOrder();
        $input->SetAppid($this->wechat->appid);
        $input->SetMch_id($this->wechat->wx_mchid);
        $input->SetBody($name);
        //$input->SetAttach($name . "Attach");
        $input->SetOut_trade_no($orderId);
        $input->SetTotal_fee($deposit);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire($expireTime);
        $input->SetGoods_tag("test_goods_tag");
        if (!empty($wx_notify_url)) {
            $input->SetNotify_url($wx_notify_url);
        } else {
            $input->SetNotify_url($this->wechat->wx_notify_url);
        }
        $input->SetTrade_type("NATIVE");
        $input->SetProduct_id($exhibitionId);

        //微信参数设置
        WeixinPay::wechatParams($this->wechat);
        $result = \WxPayApi::unifiedOrder($input);
        $url = $result["code_url"];
        return $url;
    }

    public function orderQuery($orderId)
    {

        $order = OrderPay::findOne(['order_id' => $orderId]);
        if (null == $order) {
            return ['success' => false];
        } else {
            return ['success' => true];
        }
        /*$input->SetMch_id('');
        $input->SetOut_trade_no($orderId);
        return \WxPayApi::orderQuery($input);*/

    }


}